package main

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
)

// 指纹锁（散列算法）：给数据做个 “专属标记”
// encryptPassword 模拟“加密”密码：生成盐和密码的哈希值
// 这相当于你之前的 passwordToHash 函数
func encryptPassword(password string) (salt, hash string) {
	// 1. 生成随机“盐”
	saltBytes := make([]byte, 16)
	_, err := rand.Read(saltBytes)
	if err != nil {
		panic(err) // 在实际应用中，应返回错误
	}
	salt = base64.URLEncoding.EncodeToString(saltBytes)

	// 2. 密码 + 盐，生成“指纹”（哈希值）
	hashBytes := sha256.Sum256([]byte(password + salt))
	hash = base64.URLEncoding.EncodeToString(hashBytes[:])

	return salt, hash
}

// verifyPassword 模拟“解密”并验证密码：检查输入的密码是否正确
// 它接收用户输入的密码，以及数据库中存储的盐和哈希值
func verifyPassword(inputPassword, storedSalt, storedHash string) bool {
	// 1. 使用同样的盐，对用户输入的密码进行同样的哈希计算
	inputHashBytes := sha256.Sum256([]byte(inputPassword + storedSalt))
	inputHash := base64.URLEncoding.EncodeToString(inputHashBytes[:])

	// 2. 比较计算出的哈希值和数据库中存储的哈希值是否一致
	return inputHash == storedHash
}

func main() {
	// --- 场景：用户注册 ---
	fmt.Println("--- 用户注册过程 ---")
	userPassword := "MySecretPassword123!"
	fmt.Println("用户设置的原始密码：", userPassword)

	// “加密”密码，得到盐和哈希值
	salt, hash := encryptPassword(userPassword)
	fmt.Println("生成的盐 (Salt)：", salt)
	fmt.Println("生成的密码哈希 (Hash)：", hash)
	fmt.Println("注：数据库中仅存储 盐 和 哈希值，不存储原始密码！")

	// --- 场景：用户登录 ---
	fmt.Println("\n--- 用户登录过程 ---")

	// 模拟用户输入正确的密码
	inputPassword1 := "MySecretPassword123!"
	fmt.Println("\n尝试用【正确密码】登录：", inputPassword1)
	isValid1 := verifyPassword(inputPassword1, salt, hash)
	if isValid1 {
		fmt.Println("登录成功！密码正确。")
	} else {
		fmt.Println("登录失败！密码错误。")
	}

	// 模拟用户输入错误的密码
	inputPassword2 := "WrongPassword456!"
	fmt.Println("\n尝试用【错误密码】登录：", inputPassword2)
	isValid2 := verifyPassword(inputPassword2, salt, hash)
	if isValid2 {
		fmt.Println("登录成功！密码正确。")
	} else {
		fmt.Println("登录失败！密码错误。")
	}
}
